package com.jdk.learn.thread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 有问题的售票？
 * 线程安全问题
 */
public class ThreadSaleToken implements Runnable {
    private int  totalNum=100;
    @Override
    public void run() {
        while (totalNum>0){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sale();
        }
    }

    /**
     * 第一种售票
     */
    private void sale1() {
        System.out.println("Name:"+Thread.currentThread().getName()+",售出"+(100-totalNum+1)+"张票");
        totalNum--;
    }
    /**
     * 第2种售票
     */
    private void sale2() {
        if (totalNum>0) {
            System.out.println("Name:"+Thread.currentThread().getName()+",售出"+(100-totalNum+1)+"张票");
            totalNum--;
        }
    }
    /**
     * 第3种售票
     * 正确的方式
     */
    private Object lockObject=new Object();
    private  void sale3() {
        synchronized (lockObject) {
            if (totalNum>0) {
                System.out.println("Name:" + Thread.currentThread().getName() + ",售出" + (100 - totalNum + 1) + "张票");
                totalNum--;
            }
        }
    }
    /**
     * 第4种售票
     * 此种方式锁的是this对象。this可以被回收
     * 如果由static修饰 则是类锁 垃圾回收不了
     * 正确的方式
     */
    private synchronized   void sale4() {
            if (totalNum>0) {
                System.out.println("Name:" + Thread.currentThread().getName() + ",售出" + (100 - totalNum + 1) + "张票");
                totalNum--;
            }
    }

    private static synchronized   void sale4copy() {
//            if (totalNum>0) {
//                System.out.println("Name:" + Thread.currentThread().getName() + ",售出" + (100 - totalNum + 1) + "张票");
//                totalNum--;
//            }
    }
    /**
     * 第5种售票
     * 正确的方式
     */
    private Lock lock=new ReentrantLock();
    private   void sale() {
        try {
            lock.lock();
            if (totalNum>0) {
                System.out.println("Name:" + Thread.currentThread().getName() + ",售出" + (100 - totalNum + 1) + "张票");
                totalNum--;
            }
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ThreadSaleToken threadSaleToken=new ThreadSaleToken();
        Thread t1 = new Thread(threadSaleToken, "窗口--1--");
        Thread t2 = new Thread(threadSaleToken, "窗口--2--");
        t1.start();
        t2.start();
    }
}
